package com.iakuil.app.api.controller;


import com.iakuil.app.common.core.BaseController;
import com.iakuil.app.common.core.annotation.Log;
import com.iakuil.app.common.core.domain.Result;
import com.iakuil.app.common.core.enums.OpType;
import com.iakuil.app.common.core.jsr303.constraints.Ids;
import com.iakuil.app.domain.dto.BookDto;
import com.iakuil.app.domain.dto.cmd.BookAdd;
import com.iakuil.app.domain.dto.cmd.BookEdit;
import com.iakuil.app.domain.dto.query.BookQuery;
import com.iakuil.app.domain.dto.vo.BookInfoVo;
import com.iakuil.app.domain.entity.Book;
import com.iakuil.app.service.BookService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 书籍 接口
 *
 * <p>演示级联查询场景接口。
 * <p>书籍 - 1:n -> 作者
 * <p>书籍 - 1:1 -> 出版社
 *
 * @author Kai
 * @date 2023-11-28
 */
@Tag(name = "书籍（示例）", description = "书籍接口")
@RestController
@RequestMapping("/api/v1/book")
@RequiredArgsConstructor(onConstructor = @__(@Autowired))
public class BookController extends BaseController {
    private final BookService bookService;

    @Operation(summary = "书籍详情", description = "根据ID查询书籍。")
    @Parameter(name = "id", description = "ID", required = true, in = ParameterIn.QUERY)
    @GetMapping
    public Result<BookInfoVo> doQuery(@RequestParam Long id) {
        // 对于无效的ID，应根据业务需要，返回空值或者报错。
        return success(bookService.getDetailsById(id));
    }

    @Operation(summary = "书籍列表", description = "分页查询书籍数据（幂等接口）")
    @PostMapping(value = "/list")
    public Result<BookDto> doPaging(@RequestBody BookQuery param) {
        startPage();
        return pageInfo(bookService.listByCondition(param));
    }

    @Operation(summary = "书籍新增", description = "新增书籍。")
    @Log(title = "书籍", type = OpType.INSERT)
    @PostMapping(value = "/create")
    public Result<Long> doCreate(@Validated @RequestBody BookAdd param) {
        // 基本参数校验应在转换操作之前，约早越好
        Book entity = convert(param, Book.class);
        // 业务校验不要写进事务，最好独立出来
        bookService.preChange(entity);
        return success(bookService::save, entity);
    }

    @Operation(summary = "书籍修改", description = "修改书籍。")
    @Log(title = "书籍", type = OpType.UPDATE)
    @PostMapping(value = "/edit")
    public Result<Void> doEdit(@Validated @RequestBody BookEdit param) {
        Book entity = convert(param, Book.class);
        bookService.preChange(entity);
        return success(bookService.modify(entity));
    }

    @Operation(summary = "书籍删除", description = "批量删除书籍（幂等接口）")
    @Parameter(name = "ids", description = "ID列表，逗号分隔，无需方括号", required = true, in = ParameterIn.QUERY)
    @Log(title = "书籍", type = OpType.DELETE)
    @PostMapping(value = "/remove")
    public Result<Void> doRemove(@RequestParam @Ids Long[] ids) {
        bookService.removeByIds(ids);
        // 删除接口一般是幂等的
        return success();
    }
}
